`timescale 1ns / 1ps
`include "const_def.vh"


module ex_mem(
        //input
        input               clk,
        input               rst,
        input [31:0]        _ans,  // Directly from ALU
        input [31:0]        _reg2,
        input [31:0]        _jal_dst,
        input [4:0]         _reg_waddr,


        //ctrl signal in
        input               ctrl_mem_wE,
        input [2:0]         ctrl_reg_wdataE,
        input               ctrl_reg_wE,
        input [1:0]         ctrl_bhwE,  // data type

        //output
        output [31:0]       alu_ans_,
        output [31:0]       mem_addr_,
        output [31:0]       mem_wdata_,
        output [31:0]       jal_dst_,  // JAL: jump to somewhere and store the return addess in $ra
        output [4:0]        reg_waddr_,

        //ctrl signal out
        output               ctrl_mem_wM,
        output [2:0]         ctrl_reg_wdataM,
        output               ctrl_reg_wM,
        output  [1:0]        ctrl_bhwM  // data type
    );

    // Buffer
    reg[31:0]   ans;
    reg[31:0]   reg2;
    reg[31:0]   jal_dst;
    reg[4:0]    reg_waddr;
    reg         ctrl_mem_w;
    reg[2:0]    ctrl_reg_wdata;
    reg         ctrl_reg_w;
    reg[1:0]    ctrl_bhw;

    always @ (posedge clk) begin
        if (!rst) begin
            // Reset button triggered
            ans             <=  `ZERO_32;
            reg2            <=  `ZERO_32;
            jal_dst         <=  `ZERO_32;
            reg_waddr       <=  `ZERO_5;
            ctrl_mem_w      <=  `ZERO_1;
            ctrl_reg_wdata  <=  `ZERO_3;
            ctrl_reg_w      <=  `ZERO_1;
            ctrl_bhw        <=  `ZERO_2;
        end else begin
            ans             <=  _ans;
            reg2            <=  _reg2;
            jal_dst         <=  _jal_dst;
            reg_waddr       <=  _reg_waddr;
            ctrl_mem_w      <=  ctrl_mem_wE;
            ctrl_reg_wdata  <=  ctrl_reg_wdataE;
            ctrl_reg_w      <=  ctrl_reg_wE;
            ctrl_bhw        <=  ctrl_bhwE;
        end
    end

    //��ֵ��������һ�����ź�
    assign alu_ans_             =   ans;
    assign  mem_addr_      =   ans;
    assign mem_wdata_      =   reg2;
    assign jal_dst_         =   jal_dst;
    assign reg_waddr_       =   reg_waddr;
    assign ctrl_mem_wM      =   ctrl_mem_w;
    assign ctrl_reg_wdataM  =   ctrl_reg_wdata;
    assign  ctrl_reg_wM     =   ctrl_reg_w;
    assign  ctrl_bhwM        =   ctrl_bhw;

    //����??

endmodule
